package com.shuqi.common.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.drawable.Drawable;
import android.graphics.Rect;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Environment;
import android.os.Parcelable;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebView;
import android.widget.AbsListView;
import android.widget.ListView;

import com.shuqi.application.ShuqiApplication;
import com.shuqi.common.Config;
import com.shuqi.common.FunctionsSwitch;
import com.shuqi.common.LoginHelper;
import com.shuqi.common.WebkitUrlDealer;
import com.shuqi.controller.BuildConfig;
import com.shuqi.controller.Loading;
import com.shuqi.controller.R;

/**
 * 工具类
 * 
 * @author Jianda.Yang
 * @date 2013-12-12 下午4:10:08
 * @version 1.0
 */
public class Util {
    /** 需要被替换的字符串数组：应与replaceToArray索引对应 */
    public static String[] replaceArray = {"<br>", "<br/>", "<br />", "�"};

    /** 需要被替换为的字符串数组：应与replaceArray 索引对应 */
    public static String[] replaceToArray = {"\n", "\n", "\n", ""};

    /**
     * 判定SD卡是否可用
     * 
     * @return
     */
    public static boolean isCanUseSdCard() {
        try {
            return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 获取屏幕宽度
     * 
     * @return
     */
    public static int getScreenWidth() {
        return ShuqiApplication.getContext().getResources().getDisplayMetrics().widthPixels;
    }

    /**
     * 获取屏幕高
     * 
     * @return
     */
    public static int getScreenHeight() {
        return ShuqiApplication.getContext().getResources().getDisplayMetrics().heightPixels;
    }

    /**
     * 获取软件版本
     * 
     * @param context
     * @return versionCode
     */
    public static int getVersionCode(Context context) {
        // 获取packagemanager的实例
        PackageManager packageManager = context.getPackageManager();
        // getPackageName()是你当前类的包名，0代表是获取版本信息
        int version = 0;
        PackageInfo packInfo;
        try {
            packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            version = packInfo.versionCode;
        } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return version;
    }

    /**
     * 返回当前程序版本名
     * 
     * @param context
     * @return versionName
     */
    public static String getAppVersionName(Context context) {
        String versionName = "";
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            versionName = pi.versionName;
            if (versionName == null || versionName.length() <= 0) {
                return "";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return versionName;
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context
                .getResources().getDisplayMetrics()) + 0.5f);
    }

    /**
     * 根据手机的分辨率从 sp 的单位 转成为 px(像素)
     */
    public static int sp2px(Context context, float spValue) {
        return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spValue, context
                .getResources().getDisplayMetrics()) + 0.5f);
    }

    /**
     * px to dp
     * 
     * @param px
     * @return
     */
    public static int pxToDp(int px) {
        // Log4an.e("1", "【pxtoDp】="
        // + ((int) (px / Resources.getSystem().getDisplayMetrics().density)));
        return (int) (px / Resources.getSystem().getDisplayMetrics().density);
    }

    /**
     * dp to pxs
     * 
     * @param dp
     * @return
     */
    public static int dpToPx(int dp) {
        // Log4an.e("1", "【dpToPx】=" + (int) (dp *
        // Resources.getSystem().getDisplayMetrics().density));
        return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
    }

    /**
     * 显示/隐藏输入法
     * 
     * @param context
     * @param isShow true:显示，false:隐藏
     */
    public static void inputMethodControl(Context context, boolean isShow) {
        // 当前页面切换出去后隐藏输入法
        try {
            InputMethodManager imm =
                    (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
            if (isShow) {
                imm.showSoftInputFromInputMethod(((Activity) context).getCurrentFocus()
                        .getWindowToken(), InputMethodManager.SHOW_IMPLICIT);
            } else {
                imm.hideSoftInputFromWindow(
                        ((Activity) context).getCurrentFocus().getWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
            }
        } catch (Exception e) {
        }
    }

    /**
     * 显示/隐藏输入法
     * 
     * @param context
     * @param isShow true:显示，false:隐藏
     * @param view 获取输入法焦点的view
     */
    public static void inputMethodControl(Context context, boolean isShow, View view) {
        if (view == null) {
            inputMethodControl(context, isShow);
            return;
        }
        try {
            InputMethodManager imm =
                    (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

            if (isShow) {
                imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
            } else {
                imm.hideSoftInputFromWindow(view.getWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static final boolean isWebViewProbablyCorrupt(Context context) {
        try {
            SQLiteDatabase cacheDb = context.openOrCreateDatabase("webviewCache.db", 0, null);

            if (cacheDb != null) {
                cacheDb.close();
                return false;
            }
        } catch (Throwable t) {
            Log4an.w("isWebViewProbablyCorrupt", t.toString());
        }

        return true;
    }

    /**
     * 获取MD5编码
     * 
     * @param s
     * @return
     */
    public static final String getMD5(String s) {
        try {
            byte[] btInput = s.getBytes();
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < md.length; i++) {
                int val = ((int) md[i]) & 0xff;
                if (val < 16)
                    sb.append("0");
                sb.append(Integer.toHexString(val));
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取IMEI
     * 
     * @param context
     * @return
     */
    public static String getIMEI(Context context) {
        String imei = null;
        TelephonyManager tm =
                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm != null) {
            imei = tm.getDeviceId();
        } else {
            imei = "null";
        }

        return imei;
    }

    /**
     * 获取字体高度
     * 
     * @param fontSize
     * @return
     */
    public static int getFontHeight(float fontSize) {
        Paint paint = new Paint();
        paint.setTextSize(fontSize);
        FontMetrics fm = paint.getFontMetrics();
        return (int) Math.ceil(fm.descent - fm.top) + 2;
    }

    /**
     * 获取设备density
     * 
     * @param activity
     * @return
     */
    public static float getDensity(Context activity) {
        DisplayMetrics dm = new DisplayMetrics();
        ((Activity) activity).getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.density;
    }

    /**
     * 获取文件编码类型
     * 
     * @remark 获得文件编码类型，如果是”windows-1252“,则文件的正确编码格式为"Unicode" 其他格式则尝试用GBK解析
     * @param context
     * @param filePath 文件路径
     * @return 文件编码String
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static String getTxtFileEncoding(Context context, String filePath)
            throws FileNotFoundException, IOException {
        if (context == null || TextUtils.isEmpty(filePath)) {
            return null;
        }
        String encoding = SharedPreferenceUtil.getFileEncode(context, filePath);
        if (TextUtils.isEmpty(encoding)) {
            encoding = new FileCharsetDetectorUtil().guestFileEncoding(filePath);
            if (encoding.equalsIgnoreCase("windows-1252")) {
                encoding = "Unicode";
            } else if (encoding.equalsIgnoreCase("EUC-KR") || encoding.equalsIgnoreCase("EUC-JP")
                    || encoding.equalsIgnoreCase("Shift_JIS")
                    || encoding.equalsIgnoreCase("BIG5-HKSCS") || encoding.equalsIgnoreCase("BIG5")
                    || encoding.equalsIgnoreCase("GBK") || encoding.equalsIgnoreCase("GB18030")
                    || encoding.equalsIgnoreCase("GB2312")) {
                encoding = "GBK";
            }
            SharedPreferenceUtil.setFileEncode(context, filePath, encoding);
        }
        return encoding;
    }

    /**
     * 获取文件名字
     * 
     * @param path 文件路径
     * @param filenameExtension 文件后缀名（传入时必须带有小数点的后缀名,如：.txt；为空时获取带有后缀的名称）
     * @return
     */
    public static String getSubNameFromPath(String path, String filenameExtension) {
        String name = "";
        if (TextUtils.isEmpty(filenameExtension)) {
            name = path.substring(path.lastIndexOf("/") + 1, path.length());
        } else {
            name =
                    path.substring(path.lastIndexOf("/") + 1,
                            path.length() - filenameExtension.length());
        }
        return name;
    }


    public static void checkSig(Context context) {
        if (BuildConfig.DEBUG) {
            return;
        }
        PackageManager pm = context.getPackageManager();
        try {
            PackageInfo pi =
                    pm.getPackageInfo(Config.PACKAGENAME_VERIFY, PackageManager.GET_SIGNATURES);
            Signature[] s = pi.signatures;
            int sig = s[0].hashCode();
            if (-1936262660 != sig) {
                android.os.Process.killProcess(android.os.Process.myPid());
            }
        } catch (Exception e) {
            System.exit(-1);
        }
    }


    /**
     * 获取通知栏高度
     * 
     * @return
     */
    public static int getStatusBarHeight() {
        return Resources.getSystem().getDimensionPixelSize(
                Resources.getSystem().getIdentifier("status_bar_height", "dimen", "android"));
    }

    /**
     * 获取通知栏高度
     * 
     * 注: 注意显示时机onWindowFocusChanged
     * 
     * @return
     */
    public static int getStatusBarHeight(Activity act) {
        Rect rc = new Rect();
        act.getWindow().getDecorView().getWindowVisibleDisplayFrame(rc);

        int screenHeight = getScreenHeight();
        int statusbarHeight = screenHeight - rc.height();

        return statusbarHeight;
    }

    /**
     * 应用应用显示区域
     * 
     * 注: 注意显示时机onWindowFocusChanged
     * 
     * @param act
     * @return
     */
    public static Rect getAppRect(Activity act) {
        Rect rc = new Rect();
        act.getWindow().getDecorView().getWindowVisibleDisplayFrame(rc);

        return rc;
    }

    /**
     * @Des 描述 缓存读取网络数据
     * @param inputstream
     * @param iBufferSize
     * @return
     * @throws IOException byte[]
     */
    public static byte[] getBytes(InputStream inputstream, int iBufferSize) throws IOException {
        byte[] bArr = new byte[iBufferSize];
        int iIndex = 0;
        int iLength = 0;
        int iTotalLength = 0;
        while ((iLength = inputstream.read(bArr, iIndex, bArr.length - iIndex)) != -1) {
            iIndex += iLength;
            if (iLength != -1) {
                iTotalLength += iLength;
            }
            // 如果读入大于了缓存
            if (iIndex >= bArr.length) {
                // 缓存数据
                byte[] arrbTemp = new byte[bArr.length];
                // 导入数据
                System.arraycopy(bArr, 0, arrbTemp, 0, bArr.length);
                // 新建缓存数据
                bArr = null;
                bArr = new byte[arrbTemp.length + iBufferSize];
                // 导回数据
                System.arraycopy(arrbTemp, 0, bArr, 0, arrbTemp.length);
                arrbTemp = null;
            }
        }
        byte[] bBack = new byte[iTotalLength];

        System.arraycopy(bArr, 0, bBack, 0, bBack.length);

        bArr = null;

        return bBack;
    }

    /**
     * 检查网络是否连接
     * 
     * @param context
     * @return
     */
    public static boolean isNetworkConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager =
                    (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
            if (mNetworkInfo != null) {
                return mNetworkInfo.isAvailable();
            }
        }
        return false;
    }


    /**
     * cdn解析时，替换章节内容中的特殊字符： java
     * 
     * @param content
     * @return 替换后的新内容
     */
    public static String replaceByRule(String content) {
        if (TextUtils.isEmpty(content)) {
            return "";
        }
        for (int i = 0; i < replaceArray.length && i < replaceToArray.length; i++) {
            content = content.replaceAll(replaceArray[i], replaceToArray[i]);
        }
        return content;
    }

    /** 将InputStream转换成byte[] */
    public static byte[] getBytes(InputStream is) throws IOException {
        if (is == null) {
            return null;
        }
        byte[] data = null;
        Collection<byte[]> chunks = new ArrayList<byte[]>();
        byte[] buffer = new byte[2048];
        int read = -1;
        int size = 0;
        while ((read = is.read(buffer, 0, buffer.length)) != -1) {
            if (read > 0) {
                byte[] chunk = new byte[read];
                System.arraycopy(buffer, 0, chunk, 0, read);
                chunks.add(chunk);
                size += chunk.length;
            }
        }

        if (size > 0) {
            ByteArrayOutputStream bos = null;
            try {
                bos = new ByteArrayOutputStream(size);
                for (Iterator<byte[]> itr = chunks.iterator(); itr.hasNext();) {
                    byte[] chunk = itr.next();
                    bos.write(chunk);
                }
                data = bos.toByteArray();
            } finally {
                if (bos != null) {
                    bos.close();
                }
            }
        }
        return data;
    }

    /***
     * MD5编码
     * 
     * @param 加密内容
     * @return
     */
    public static final String MD5(String s) {
        try {
            byte[] btInput = s.getBytes();
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < md.length; i++) {
                int val = ((int) md[i]) & 0xff;
                if (val < 16)
                    sb.append("0");
                sb.append(Integer.toHexString(val));
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 字符串null判断
     * 
     * @param str
     * @return
     */
    public static String isNull(String str) {
        return str == null ? "" : str;
    }

    /**
     * 关闭软键盘
     * 
     * @param context
     * @param view
     */
    public static void hidesoftkeyboard(Context context, View view) {
        InputMethodManager imm =
                (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }

    /**
     * <b>书旗接口</b> 的用户的加密验证 <br>
     * PostTime: timeStamp <br>
     * PostToken: (timeStamp + userId) --> SHA-1 --> MD5
     * 
     * @param params 可以为 null
     * @param userId
     * @return
     */
    public static List<BasicNameValuePair> encryptUrl_ShuQi(List<BasicNameValuePair> params,
            String userId) {
        // 书旗后端验证
        if (params == null) {
            params = new ArrayList<BasicNameValuePair>();
        }
        String timestamp = String.valueOf(System.currentTimeMillis());
        String md5_key = Util.MD5(LoginHelper.Encrypt(timestamp + userId));
        params.add(new BasicNameValuePair("PostTime", timestamp));// 时间戳
        params.add(new BasicNameValuePair("PostToken", md5_key));// md5
        return params;
    }

    /**
     * <b>App接口</b> 的加密验证 <br>
     * timestamp: timeStamp <br>
     * key: (key + timestamp) --> MD5
     * 
     * @param params 可以为 null
     * @param key 约定密钥 3e30ef50cbg32gd92deb3ftd2321e654
     * @return
     */
    public static List<BasicNameValuePair> encryptUrl_App(List<BasicNameValuePair> params,
            String key) {
        // App接口后端验证
        if (params == null) {
            params = new ArrayList<BasicNameValuePair>();
        }
        String timestamp = String.valueOf(System.currentTimeMillis());
        String md5_key = Util.MD5(key + timestamp);
        params.add(new BasicNameValuePair("key", md5_key));// md5
        params.add(new BasicNameValuePair("timestamp", timestamp));// 时间戳
        return params;
    }

    /**
     * 删除文件
     * 
     * @param filepath
     * @return
     */
    public static boolean fileDel(String filepath) {
        File file = new File(filepath);
        if (file.exists()) {
            if (file.isFile()) {
                file.delete();
            }
        }
        file = null;
        return true;
    }

    /**
     * 判断SD卡上的文件夹是否存在
     * 
     * @param fileDir
     * @return
     */
    public static boolean isFileExist(String fileDir) {
        if (TextUtils.isEmpty(fileDir)) {
            return false;
        }
        File file = new File(fileDir);
        return file.exists();
    }


    /**
     * 递归删除目录
     * 
     * @param dir
     */
    public static void forceDelDir(File dir) {
        if (dir == null || dir.isFile()) {
            return;
        }
        File[] files = dir.listFiles();

        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) {
                files[i].delete();
            } else {
                forceDelDir(files[i]);
            }
        }
    }

    /**
     * 拷贝文件
     * 
     * @param fis
     * @param tofile
     * @return
     */
    public static boolean fileCopyFile(InputStream fis, String toFilePath) {
        if (fis == null || TextUtils.isEmpty(toFilePath)) {
            return false;
        }
        FileOutputStream fos;
        try {

            fos = new FileOutputStream(toFilePath);
            byte[] buf = new byte[1024];
            int i = 0;
            while ((i = fis.read(buf)) != -1) {
                fos.write(buf, 0, i);
            }
            fis.close();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 获取系统SDK版本
     * 
     * @return
     */
    public static int getOSVersion() {
        return android.os.Build.VERSION.SDK_INT;
    }

    /** 添加桌面快捷方式 */
    public static void createShorCut(Context context) {
        if (FunctionsSwitch.isCreatedShorCut(context)) {
            return;
        }
        Intent shortcutIntent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
        Parcelable icon = Intent.ShortcutIconResource.fromContext(context, R.drawable.icon);
        shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.app_name));
        shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
        shortcutIntent.putExtra("duplicate", false);

        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setComponent(new ComponentName(context.getPackageName(), Loading.class.getName()));
        shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);

        context.sendBroadcast(shortcutIntent);
        FunctionsSwitch.createShorCutFinish(context);
    }

    /**
     * 时间戳转换为时间字符串
     * 
     * @param cc_time
     * @return
     */
    public static String getStrTime(String cc_time) {
        String re_StrTime = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        long lcc_time = Long.valueOf(cc_time);
        re_StrTime = sdf.format(new Date(lcc_time * 1000L));
        return re_StrTime;
    }

    public static void loadUrl(Activity act, WebView webView, String url) {

        if (webView == null || url == null)
            return;// 不处理

        WebkitUrlDealer urlDealer = new WebkitUrlDealer(act);

        if (!TextUtils.isEmpty(url) && url.startsWith("http")) {
            url = urlDealer.dealUrl(new StringBuilder(50).append(url));
        }

        webView.loadUrl(url);// 点击连接从自身打开

        // int sdkVersion = Build.VERSION.SDK_INT;
        //
        // if (sdkVersion <= Build.VERSION_CODES.ECLAIR_MR1) {
        // webView.loadUrl(url);// 点击连接从自身打开
        // } else {
        // Map<String, String> headers = new HashMap<String, String>();
        // headers.put("Accept-Encoding", "gzip"); //gzip压缩
        // webView.loadUrl(url, headers);
        // }

    }

    /**
     * 隐藏4.0以上的 NavigationBar
     */
    public static void hideNavigationBar(Activity act) {
        if (act == null || act.isFinishing())
            return;


        if (Build.VERSION.SDK_INT >= 14) {

            try {

                Class<View> c = View.class;
                Method setSystemUiVisibilityMethod =
                        c.getDeclaredMethod("setSystemUiVisibility", int.class);

                if (setSystemUiVisibilityMethod != null) {
                    int systemUiVisibility = 2;// View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    setSystemUiVisibilityMethod.invoke(act.getWindow().getDecorView(),
                            systemUiVisibility);
                }

            } catch (Throwable e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 修改listview默认的滑动条
     */
    public static void setScrollBar(Activity act, ListView listview, int imgId) {
        if (Util.getOSVersion() >= 19) {
            return;
        }
        try {
            Field f = AbsListView.class.getDeclaredField("mFastScroller");
            f.setAccessible(true);
            Object o = f.get(listview);
            f = f.getType().getDeclaredField("mThumbDrawable");
            f.setAccessible(true);
            Drawable drawable = (Drawable) f.get(o);
            drawable = act.getResources().getDrawable(imgId);
            f.set(o, drawable);
        } catch (Exception e) {
            Log4an.e("CataLogLayout", e.toString());
        }
    }
}
